package org.jeecg.modules.flower.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.utils.UuidUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.chvegetable.entity.FlowerTagBook;
import org.jeecg.modules.chvegetable.service.IFlowerTagBookService;
import org.jeecg.modules.flower.entity.*;
import org.jeecg.modules.flower.mapper.FlowerOutorderMapper;
import org.jeecg.modules.flower.mapper.FlowerOutorderPrtMapper;
import org.jeecg.modules.flower.mapper.FlowerOutorderinfoMapper;
import org.jeecg.modules.flower.service.IFlowerOutorderNewService;
import org.jeecg.modules.flower.service.IFlowerOutorderinfoService;
import org.jeecg.modules.flower.service.XsglService;
import org.jeecg.modules.flower.util.CommonUtil;
import org.jeecg.modules.flowerutil.controller.PeriodController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 出库单主表 新新新新新新新新新
 */
@Service
@Slf4j
public class FlowerOutorderNewServiceImpl extends ServiceImpl<FlowerOutorderMapper, FlowerOutorder> implements IFlowerOutorderNewService {

    @Autowired
    private FlowerOutorderMapper flowerOutorderMapper;
    @Autowired
    private FlowerOutorderinfoMapper flowerOutorderinfoMapper;
    @Autowired
    private IFlowerOutorderinfoService flowerOutorderinfoService;

    @Autowired
    private XsglService xsglService;
    @Autowired
    private IFlowerTagBookService flowerTagBookService;

    @Autowired
    private FlowerOutorderPrtMapper flowerOutorderPrtMapper;

    //  新状态变化：   3（占用库存的--审核中）--》4财务已审核--备货中--->0--（已发货）-->2（已结算） 2023年3月1日15:03:17
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveMainNew(FlowerOutorder flowerOutorder, List<FlowerOutorderinfo> flowerOutorderinfoList) throws IOException {
        log.info("接收销售系统订单" + flowerOutorder.getSealNo() + "==================");
        //自动生成出库单号
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
        String dateNo = simpleDateFormat.format(new Date());
        String sealNo = flowerOutorder.getSealNo();
        LambdaQueryWrapper<FlowerOutorder> lambdaQuerySealNo = new LambdaQueryWrapper<>();
        lambdaQuerySealNo.eq(FlowerOutorder::getSealNo, sealNo);
        lambdaQuerySealNo.ne(FlowerOutorder::getState, 9);
        List<FlowerOutorder> list1 = this.list(lambdaQuerySealNo);
        if (StringUtils.isNotBlank(sealNo) && list1.size() > 0) {
            throw new RuntimeException(sealNo + "销售单已经生成过出库单了" + list1.get(0).getOrderNo());
        }


        String refex = "CK" + dateNo;
        LambdaQueryWrapper<FlowerOutorder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(FlowerOutorder::getOrderNo, refex);
        lambdaQueryWrapper.orderByDesc(FlowerOutorder::getOrderNo);
        List<FlowerOutorder> list = this.list(lambdaQueryWrapper);
        String oldNo = "";
        if (list.size() > 0) {
            oldNo = list.get(0).getOrderNo();
        }
        String no1 = CommonUtil.getNo("CK", oldNo, 5);
        flowerOutorder.setOrderNo(no1);//自动生成出库单号
        if (StringUtils.isBlank(flowerOutorder.getPeriod())) {
            PeriodController periodController = new PeriodController();
            String currentPeriod = periodController.getCurrentPeriod();
            flowerOutorder.setPeriod(currentPeriod);
        }
        //自动生成出库单号========end====

        String source = flowerOutorder.getSource();
        String userid = flowerOutorder.getUserid();
        if (StringUtils.isBlank(source)) {
            //来源为空时设置默认为“销售系统”
            flowerOutorder.setSource("销售系统");
        }
        if (StringUtils.isBlank(userid)) {
            throw new RuntimeException("客户id为空，请重新选择客户信息！");
        }

        BigDecimal sumNumber = BigDecimal.ZERO;
        BigDecimal sumMoney = new BigDecimal("0");
        for (FlowerOutorderinfo flowerOutorderinfo : flowerOutorderinfoList) {
            BigDecimal number = flowerOutorderinfo.getNumber();
            sumNumber = sumNumber .add( number );
            sumMoney = sumMoney.add(flowerOutorderinfo.getTotalprice());
        }
        flowerOutorder.setNumber(sumNumber);
        flowerOutorder.setTotalprice(sumMoney);
//        -1草稿，0库管已确认出库，1运管已审核，2运管已确认，3提交审核，4财务已审核, 9删除
        flowerOutorder.setState(3);//备货中
        flowerOutorderMapper.insert(flowerOutorder);

        Map<String, String> costByStorehouse = CommonUtil.getCostByStorehouse();
        if (flowerOutorderinfoList != null && flowerOutorderinfoList.size() > 0) {
            for (FlowerOutorderinfo entity : flowerOutorderinfoList) {
                //外键设置
                entity.setOrderId(flowerOutorder.getId());

                if (StringUtils.isNotBlank(entity.getStorehouse())) {
                    String cost1 = costByStorehouse.get(entity.getStorehouse());
                    entity.setCost(cost1);
                }
                flowerOutorderinfoMapper.insert(entity);
            }
        } else {
            throw new RuntimeException("没有订单详情");
        }

        String wrangContent = "";
        int showNum = 1;
        Map<String, String> greenHouseNames = CommonUtil.getGreenHouseNames();
        Map<String, String> houseNames = CommonUtil.getHouseNames();

        String id = flowerOutorder.getId();
        List<FlowerTagBook> lowBookList = flowerTagBookService.getLowBookList(id);
        for (FlowerTagBook flowerTagBook : lowBookList) {
            wrangContent = wrangContent + "  " + showNum + "、提示：" + greenHouseNames.get(flowerTagBook.getSourceGreenhouse()) + houseNames.get(flowerTagBook.getStorehouse()) + flowerTagBook.getVariety() + flowerTagBook.getVarietyCode() + "，长度：" + flowerTagBook.getFlowerPoleLength() + "-数量不足,还差" + (flowerTagBook.getNumber()) + "  ；";
            showNum++;
        }
        if (StringUtils.isNotBlank(wrangContent)) {
            throw new RuntimeException(wrangContent);
        }
        // 占用 台账数据-----gf  2023年3月1日15:39:48   --start---
        Integer integer = flowerTagBookService.lockTagnumfroOut(id);
//        校验台账数据是否有负数。
        Integer integer1 = flowerTagBookService.checkBooksIsErr();
        if (integer1 > 0) {
            throw new RuntimeException("库存不够，请联系管理员！");
        }
        // 占用 台账数据-----gf  2023年3月1日15:39:48    --end---
        return "";
    }

    //推到库管员
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String toHouseSure(String sealNo) {
        LambdaQueryWrapper<FlowerOutorder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FlowerOutorder::getSealNo, sealNo);
        FlowerOutorder flowerOutorder = this.getOne(queryWrapper);
        // 修改主表状态
        flowerOutorder.setState(4); //
        flowerOutorder.setFinaSureTime(new Date());
        flowerOutorder.setFinaSureUser("销售系统");

        this.updateById(flowerOutorder);
        return "推送到库管员成功";
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delMain(FlowerOutorder flowerOutorder) {
        String id = flowerOutorder.getId();
        // 归还占用 台账数据-----gf  2023年3月1日15:39:48   --start---
        if (flowerOutorder.getState() == 1 || flowerOutorder.getState() == 3 || flowerOutorder.getState() == 4) {
            flowerTagBookService.lockTagnumfroOutBack(id);
//            校验台账数据是否有负数。
            Integer integer1 = flowerTagBookService.checkBooksIsErr();
            if (integer1 > 0) {
                throw new RuntimeException("库存不够，请联系管理员！");
            }
        }
        // 归还占用 台账数据-----gf  2023年3月1日15:39:48    --end--


        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        flowerOutorder.setState(9);//删除
        flowerOutorder.setRemarks(StringUtils.isBlank(flowerOutorder.getRemarks()) ? (sysUser.getRealname() + sysUser.getUsername() + "删除" + format.format(new Date())) : (flowerOutorder.getRemarks() + "\n" + sysUser.getRealname() + sysUser.getUsername() + "删除" + format.format(new Date())));
        this.updateById(flowerOutorder);

        List<FlowerOutorderinfo> flowerOutorderinfoList = flowerOutorderinfoMapper.selectByMainId(id);
        flowerOutorderinfoMapper.deleteByMainId(id);//删除子表
        //改变子表的id，
        for (FlowerOutorderinfo flowerOutorderinfo : flowerOutorderinfoList) {
            flowerOutorderinfo.setId(UuidUtils.getUUID());
//            UpdateWrapper<FlowerOutorderinfo> updateWrapper = new UpdateWrapper<>();
//            updateWrapper.eq("order_id", id);
//            flowerOutorderinfoMapper.update(flowerOutorderinfo, updateWrapper);
        }
        flowerOutorderinfoService.saveBatch(flowerOutorderinfoList);//修改子表id后新增子表
    }

    //分组查询入库的品类等信息，用于销售系统的价格编辑
    @Override
    public IPage<FlowerTagInfo> getFlowerVarietysALL(IPage<FlowerTagInfo> page, Wrapper<FlowerTagInfo> wrapper) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        return baseMapper.getFlowerVarietysALL(page, wrapper, sysUser.getId());
    }


    /**
     * 库管确认
     *
     * @return int
     * @descriptionauthor
     * @author gf
     * 2023-3-13 14:08
     * [id, infoListsForTnumber]
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public int sureOutDo(String id, List<FlowerOutorderinfo> infoListsForTnumber) throws IOException {
        int rest = 0;
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        FlowerOutorder outOrder = this.getById(id);
        for (FlowerOutorderinfo flowerOutorderinfo : infoListsForTnumber) {
            flowerOutorderinfoMapper.updateById(flowerOutorderinfo);
        }
        //进行库管确认出库会签判断-------------start----------2023年3月6日11:21:12
        //1、存在几个库房负责人，List<strin >
        List<FlowerStorehouse> flowerStorehouses = flowerOutorderMapper.selectStoreByOrderID(id);
        int inNums = 0;
        for (FlowerStorehouse flowerStorehouse : flowerStorehouses) {
            String personcode = flowerStorehouse.getPersoncode();
            if (StringUtils.isBlank(personcode)) {
                throw new RuntimeException("请设置" + flowerStorehouse.getName() + "的库管管理员！");
            }
            String[] personcodes = personcode.split(",");
            for (String code : personcodes) {
                if (sysUser.getUsername().equals(code)) {
                    inNums++;
                }
            }
        }
        if (inNums <= 0) {
            throw new RuntimeException("您不是仓库出库员，请联系管理员！");
        }
        String sureoutuser = outOrder.getSureoutuser();
//        String sureouttimes = outOrder.getSureouttimes();
        if (StringUtils.isBlank(sureoutuser)) {
            sureoutuser = "''";
        }
//        if (StringUtils.isBlank(sureouttimes)) {
//            sureouttimes = "''";
//        }
        if (sureoutuser.indexOf(sysUser.getRealname()) >= 0) {
            throw new RuntimeException("您已经确认出库！正等待其余仓库管理员确认！");
        } else {
            for (int i = 0; i < inNums; i++) {
                //一次性插入多个确认人名，解决多个仓库是同一个库管员问题。
                sureoutuser = sureoutuser + "," + sysUser.getRealname();
//                sureouttimes = sureouttimes + "," + sysUser.getRealname() + format.format(new Date());
            }
            outOrder.setSureoutuser(sureoutuser.replaceAll("'',", ""));
//            outOrder.setSureouttimes(sureouttimes.replaceAll("'',", ""));
            this.updateById(outOrder);
        }
        String sureouttimesNew2 = outOrder.getSureoutuser();
        String[] split = sureouttimesNew2.split(",");
        if (flowerStorehouses.size() != split.length) {
            return -99;
//            ("正在等待其他仓库员管理员进行确认");
        }
        //进行库管确认出库会签判断-------------end----------

        if (outOrder.getState() == 0) {
            throw new RuntimeException("您已经成功出库过了");
        }
        if (outOrder.getState() != 4) {
            throw new RuntimeException("请先进行财务审核");
        }

        //修改主表状态
        outOrder.setState(0);
        outOrder.setSureouttime(new Date());
        outOrder.setStockOutUser(outOrder.getSureoutuser());//更新出库人
        outOrder.setStockOutUserid(sysUser.getId());

        QueryWrapper<FlowerOutorderinfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(  tnumber   ) as number, sum(totalprice) as totalprice");
        queryWrapper.eq("order_id", id);
        FlowerOutorderinfo flowerOutorderinfoServiceOne = flowerOutorderinfoMapper.selectOne(queryWrapper);
        outOrder.setNumber(flowerOutorderinfoServiceOne.getNumber());
        outOrder.setTotalprice(flowerOutorderinfoServiceOne.getTotalprice());

        //扣减库存-----gf  2023年2月11日14:57:37   --start---
        Integer integer = flowerTagBookService.subBookInfoFromOutOrder(id);
//        校验台账数据是否有负数。
        Integer integer1 = flowerTagBookService.checkBooksIsErr();
        if (integer1 > 0) {
            throw new RuntimeException("库存不够！");
        }
        //扣减库存-----gf  2023年2月11日14:57:37   --end---

        this.updateById(outOrder);

        String source = outOrder.getSource();
        if ("销售系统".equals(source) || "补货".equals(source)) {
            //调用通知销售系统 ，已经发货
            xsglService.senOutOrderTnumbers(outOrder.getSealNo(), outOrder.getOrderNo(), sysUser.getRealname(), true, "", infoListsForTnumber);
        }
        return rest;
    }

    //库管出库- 撤销
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public int sureOutDoBack(String id) throws IOException {
        int rest = 0;
        FlowerOutorder byId = this.getById(id);
        if (byId == null || byId.getState() != 0) {
            throw new RuntimeException("请先确认出库后才能撤销");
        }
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        if (!"admin".equals(sysUser.getUsername()) && !"wxb".equals(sysUser.getUsername()) && !"18887741417".equals(sysUser.getUsername()) && !"10031316".equals(sysUser.getUsername())) {
            throw new RuntimeException("管理员才能撤销确认出库！");
        }
        //扣减库存-----gf  2023年2月11日14:57:37   --start---
        Integer integer = flowerTagBookService.subBookInfoFromOutOrderBack(id);
//        校验台账数据是否有负数。
        Integer integer1 = flowerTagBookService.checkBooksIsErr();
        if (integer1 > 0) {
            throw new RuntimeException("库存不够！请联系管理员");
        }
        //扣减库存-----gf  2023年2月11日14:57:37   --end---

        // 修改主表状态
        byId.setState(4); //  4（占用库存的--备货中）
        byId.setStockOutUser("");//更新出库人
        byId.setStockOutUserid("");
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        byId.setSureouttimes(byId.getSureouttimes() + ",【" + sysUser.getRealname() + format.format(new Date()) + "撤销】");
        byId.setSureoutuser("");
        byId.setSureouttime(null);
        this.updateById(byId);

        String source = byId.getSource();
        if ("销售系统".equals(source) || "补货".equals(source)) {
            //调用通知销售系统 ，库管出库- 撤销
            List<FlowerOutorderinfo> infoListsForTnumber = new ArrayList<>();
            xsglService.sureOutBack(byId.getSealNo());
        }

        //删除扫码出库关联数据
        try {
            QueryWrapper<FlowerOutorderPrt> prtQueryWrapper = new QueryWrapper<>();
            prtQueryWrapper.eq("order_no", byId.getOrderNo());
            flowerOutorderPrtMapper.delete(prtQueryWrapper);
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return rest;
    }

    //结算
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public String pipBySealNo(String sealNo) {
        LambdaQueryWrapper<FlowerOutorder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FlowerOutorder::getSealNo, sealNo);
        queryWrapper.eq(FlowerOutorder::getState, 0);
        FlowerOutorder flowerOutorder = this.getOne(queryWrapper);
        if (flowerOutorder != null) {
            // 修改主表状态
            flowerOutorder.setState(2); //  结算
            flowerOutorder.setSurepipeuser("销售系统");// 结算
            flowerOutorder.setSurepipetime(new Date());
            this.updateById(flowerOutorder);
            log.info("销售系统进行结算。。" + sealNo);
        } else {
            log.error("销售系统进行结算。。失败，该订单已经不满足待结算状态。" + sealNo + " " + new Date());
            return "结算失败！";
        }
        return "结算成功";
    }

    //冲红
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void redOutOrderByNos(String orderBo, String sealNo, String sealNoNew, List<FlowerOutorderinfo> flowerOutorderinfoList) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipals().getPrimaryPrincipal();
        LambdaQueryWrapper<FlowerOutorder> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(orderBo)) {
            queryWrapper.eq(FlowerOutorder::getOrderNo, orderBo);
        }
        if (StringUtils.isNotBlank(sealNo)) {
            queryWrapper.eq(FlowerOutorder::getSealNo, sealNo);
        }
        if(StringUtils.isBlank(orderBo)&& StringUtils.isBlank(sealNo)){
            throw new RuntimeException("出库单号与销售单号不能同时为空！");
        }
        FlowerOutorder flowerOutorder = this.getOne(queryWrapper);
        if (flowerOutorder == null) {
            throw new RuntimeException("未找到数据！");
        }
        Integer state = flowerOutorder.getState();
        if (state != 0 && state != 2) {
            throw new RuntimeException("未出库或者未结算数据，不可进行冲红！");
        }
        String uuid = UuidUtils.getUUID();
        BigDecimal totalNum = BigDecimal.ZERO;
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (FlowerOutorderinfo flowerOutorderinfo : flowerOutorderinfoList) {
            flowerOutorderinfo.setOrderId(uuid);
            totalNum  = totalNum.add(flowerOutorderinfo.getNumber() );

            flowerOutorderinfo.setNumber(BigDecimal.ZERO.subtract( flowerOutorderinfo.getNumber()));
//            flowerOutorderinfo.setTnumber(flowerOutorderinfo.getNumber());
            totalPrice = totalPrice.add(flowerOutorderinfo.getTotalprice());
        }


        FlowerOutorder flowerOutorderRed = new FlowerOutorder();
        flowerOutorderRed.setId(uuid);
        flowerOutorderRed.setOrderNo("CH-" + flowerOutorder.getOrderNo());
        flowerOutorderRed.setSealNo(sealNoNew);
        flowerOutorderRed.setOrderType(flowerOutorder.getOrderType());
        if (totalNum.compareTo(BigDecimal.ZERO) > 0) {
            flowerOutorderRed.setNumber(totalNum);
        } else {
            flowerOutorderRed.setNumber(flowerOutorder.getNumber());
        }
        if (totalPrice.compareTo(BigDecimal.ZERO) > 0) {
            flowerOutorderRed.setTotalprice(totalPrice);
        } else {
            flowerOutorderRed.setTotalprice(flowerOutorder.getTotalprice());
        }
//        flowerOutorderRed.setDiscprice(flowerOutorder.getDiscprice());
        flowerOutorderRed.setStockInTime(new Date());
        flowerOutorderRed.setStockOutUser(sysUser.getRealname());
        flowerOutorderRed.setStockOutUserid(sysUser.getId());
        flowerOutorderRed.setCarNo(flowerOutorder.getCarNo());
        flowerOutorderRed.setCarDerver(flowerOutorder.getCarDerver());
        flowerOutorderRed.setCarPhone(flowerOutorder.getCarPhone());
        flowerOutorderRed.setUserid(flowerOutorder.getUserid());
        flowerOutorderRed.setUser(flowerOutorder.getUser());
        flowerOutorderRed.setPhone(flowerOutorder.getPhone());
        flowerOutorderRed.setTouser(flowerOutorder.getTouser());
        flowerOutorderRed.setTophone(flowerOutorder.getTophone());
        flowerOutorderRed.setAddress(flowerOutorder.getAddress());
        flowerOutorderRed.setLogistics(flowerOutorder.getLogistics());
        flowerOutorderRed.setBusinessPerson(flowerOutorder.getBusinessPerson());
        flowerOutorderRed.setSource(flowerOutorder.getSource());
        flowerOutorderRed.setIsinvoice(flowerOutorder.getIsinvoice());
        flowerOutorderRed.setRemarks("对" + flowerOutorder.getSealNo() + "冲红");
        flowerOutorderRed.setState(2);

        if (flowerOutorderinfoList == null || flowerOutorderinfoList.size() == 0) {
//            flowerOutorderinfoMapper.redInfosByMainID(flowerOutorder.getId(), uuid);
        } else {
            flowerOutorderinfoService.saveBatch(flowerOutorderinfoList);
        }
        this.save(flowerOutorderRed);


        //更改台账数
        //扣减库存-----gf  2023年4月10日14:36:45   --start---
//        Integer integer = flowerTagBookService.subBookInfoFromOutOrderByRed(flowerOutorderRed.getId());
//        校验台账数据是否有负数。
        flowerTagBookService.checkBooksIsErr();
        //扣减库存-----gf   2023年4月10日14:36:45   --end---


    }
}
